import 'package:flutter/foundation.dart' hide Category;
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/transaction.dart';
import '../services/database_service.dart';
import '../services/exchange_rate_service.dart';
import '../services/notification_manager.dart';
import '../services/data_sync_service.dart';
import '../main.dart';

class TransactionProvider with ChangeNotifier {
  final DatabaseService _databaseService = DatabaseService();
  DataSyncService? _dataSyncService;
  List<Transaction> _transactions = [];
  bool _isLoading = false;
  bool _isSyncing = false;
  bool _hasError = false;
  DateTime? _lastSyncTime;

  // 获取同步状态
  DateTime? get lastSyncTime => _lastSyncTime;
  bool get isSyncing => _isSyncing;
  bool get hasError => _hasError;

  // 初始化数据同步服务
  Future<void> initializeDataSync() async {
    final prefs = await SharedPreferences.getInstance();
    _dataSyncService = DataSyncService(prefs);

    // 启动时检查数据一致性，但不自动同步
    _checkDataConsistency();
  }

  // 检查数据一致性
  Future<void> _checkDataConsistency() async {
    if (_dataSyncService == null) return;

    try {
      final localData = _dataSyncService!.loadLocalData();
      if (localData != null) {
        final isDataValid = await _dataSyncService!.compareData(localData);
        if (!isDataValid) {
          _hasError = true;
          if (navigatorKey.currentContext != null) {
            ScaffoldMessenger.of(navigatorKey.currentContext!).showSnackBar(
              const SnackBar(content: Text('检测到数据不一致，请从GitHub下载最新数据')),
            );
          }
        }
      }
    } catch (e) {
      debugPrint('检查数据一致性时出错: $e');
      _hasError = true;
    }
  }

  // 同步数据
  Future<void> syncData() async {
    if (_isSyncing) return;

    try {
      _isSyncing = true;
      _hasError = false;
      notifyListeners();

      if (_dataSyncService == null) {
        throw Exception('数据同步服务未初始化，请重启应用');
      }

      // 获取本地数据
      final localData = _dataSyncService!.loadLocalData();
      if (localData == null) {
        throw Exception('本地数据为空，请先添加一些交易记录');
      }

      // 上传到 GitHub
      await _dataSyncService!.uploadDataToGitHub(localData);

      _lastSyncTime = DateTime.now();
      _hasError = false;
    } catch (e) {
      _hasError = true;
      debugPrint('同步数据失败: $e');
      rethrow;
    } finally {
      _isSyncing = false;
      notifyListeners();
    }
  }

  // 更新本地交易数据
  Future<void> _updateLocalTransactions(Map<String, dynamic>? data) async {
    try {
      if (data == null) {
        throw Exception('下载的数据为空');
      }

      if (data['transactions'] == null) {
        throw Exception('下载的数据中缺少transactions字段');
      }

      if (data['transactions'] is! List) {
        throw Exception('下载的数据中transactions字段不是列表格式');
      }

      // 清空现有数据
      await _databaseService.clearTransactions();

      // 解析并添加新数据
      final List<dynamic> transactionsData =
          data['transactions'] as List<dynamic>;
      int successCount = 0;
      int failCount = 0;

      for (final transactionData in transactionsData) {
        try {
          final transaction = Transaction.fromJson(transactionData);
          await _databaseService.insertTransaction(transaction);
          successCount++;
        } catch (e) {
          debugPrint('解析交易记录失败: $e');
          failCount++;
        }
      }

      debugPrint('成功导入 $successCount 条记录，失败 $failCount 条记录');

      // 重新加载数据
      await loadTransactions();
    } catch (e) {
      debugPrint('更新本地交易数据失败: $e');
      rethrow;
    }
  }

  // 测试数据同步功能
  Future<bool> testDataSync() async {
    if (_dataSyncService == null) {
      throw Exception(
        'DataSyncService not initialized. Call initializeDataSync() first.',
      );
    }
    try {
      return await _dataSyncService!.testDataSync();
    } catch (e) {
      debugPrint('测试数据同步失败: $e');
      return false;
    }
  }

  // 获取所有交易记录
  List<Transaction> get transactions => _transactions;

  // 获取收入交易记录
  List<Transaction> get incomeTransactions =>
      _transactions
          .where((transaction) => transaction.type == TransactionType.income)
          .toList();

  // 获取支出交易记录
  List<Transaction> get expenseTransactions =>
      _transactions
          .where((transaction) => transaction.type == TransactionType.expense)
          .toList();

  // 获取转换后的交易记录（用于UI显示，已统一为基准货币）
  List<Transaction> get convertedTransactions => _convertedTransactions;

  // 获取总收入（转换为基准货币）
  double get totalIncome => _convertedIncomeTransactions.fold(
    0,
    (previousValue, transaction) => previousValue + transaction.amount,
  );

  // 获取总支出（转换为基准货币）
  double get totalExpense => _convertedExpenseTransactions.fold(
    0,
    (previousValue, transaction) => previousValue + transaction.amount,
  );

  // 获取余额
  double get balance => totalIncome - totalExpense;

  // 获取本月总收入
  double get monthlyIncome {
    final now = DateTime.now();
    final monthStart = DateTime(now.year, now.month, 1);
    return _convertedIncomeTransactions
        .where((t) => !t.date.isBefore(monthStart))
        .fold(0, (prev, t) => prev + t.amount);
  }

  // 获取本月总支出
  double get monthlyExpense {
    final now = DateTime.now();
    final monthStart = DateTime(now.year, now.month, 1);
    return _convertedExpenseTransactions
        .where((t) => !t.date.isBefore(monthStart))
        .fold(0, (prev, t) => prev + t.amount);
  }

  // 获取本月余额
  double get monthlyBalance => monthlyIncome - monthlyExpense;

  // 获取转换后的收入交易记录
  List<Transaction> get _convertedIncomeTransactions =>
      _convertedTransactions
          .where((transaction) => transaction.type == TransactionType.income)
          .toList();

  // 获取转换后的支出交易记录
  List<Transaction> get _convertedExpenseTransactions =>
      _convertedTransactions
          .where((transaction) => transaction.type == TransactionType.expense)
          .toList();

  // 转换后的交易记录（用于计算总额）
  List<Transaction> _convertedTransactions = [];

  // 加载状态
  bool get isLoading => _isLoading;

  // 初始化：从数据库加载所有交易记录
  Future<void> loadTransactions() async {
    _setLoading(true);

    try {
      _transactions =
          (await _databaseService.getTransactions()).cast<Transaction>();
      // 按日期排序（最新的在前）
      _transactions.sort((a, b) => b.date.compareTo(a.date));

      // 转换交易记录到基准货币
      await _convertTransactionsToBased();
    } catch (e) {
      // print('加载交易记录时出错: $e');
    } finally {
      _setLoading(false);
    }
  }

  // 添加交易记录
  Future<void> addTransaction(Transaction transaction) async {
    try {
      // 核心操作：立即更新UI和数据库
      await _databaseService.insertTransaction(transaction);
      _transactions.insert(0, transaction); // 插入到列表开头
      _transactions.sort((a, b) => b.date.compareTo(a.date));
      await _convertTransactionsToBased(); // 重新计算转换后的列表
      notifyListeners(); // 立即通知UI更新

      // 非核心操作：在后台执行，不阻塞UI
      _performPostTransactionTasks(transaction);
    } catch (e) {
      debugPrint('添加交易记录时出错: $e');
      _hasError = true;
      notifyListeners();

      // 只在出错时同步到GitHub
      if (_dataSyncService != null) {
        try {
          final localData = {
            'transactions': _transactions.map((t) => t.toJson()).toList(),
            'lastSync': DateTime.now().toIso8601String(),
          };
          await _dataSyncService!.saveDataLocally(localData);
          await syncData(); // 同步到GitHub
        } catch (e) {
          debugPrint('自动同步失败: $e');
        }
      }
      rethrow;
    }
  }

  // 后台执行的额外任务
  Future<void> _performPostTransactionTasks(Transaction transaction) async {
    final notificationManager = NotificationManager();

    // 1. 发送交易成功通知
    await notificationManager.sendTransactionSuccessNotification(transaction);

    // 2. 检查大额支出提醒
    await notificationManager.sendLargeExpenseAlert(transaction);

    // 3. 检查预算警告
    if (transaction.type == TransactionType.expense) {
      try {
        final prefs = await SharedPreferences.getInstance();
        final budgetKey = 'budget_${transaction.category.name}';
        final budgetLimit = prefs.getDouble(budgetKey);

        if (budgetLimit != null && budgetLimit > 0) {
          // 统计本月该类别的总支出
          final now = DateTime.now();
          final monthStart = DateTime(now.year, now.month, 1);
          double categoryExpense = 0;
          for (final t in _convertedExpenseTransactions) {
            if (t.category == transaction.category &&
                t.date.isAfter(monthStart.subtract(const Duration(days: 1))) &&
                t.date.isBefore(now.add(const Duration(days: 1)))) {
              categoryExpense += t.amount;
            }
          }
          final percentage = categoryExpense / budgetLimit * 100;
          // 发送预算警告通知
          await notificationManager.sendBudgetWarning(
            category: transaction.category.name,
            currentAmount: categoryExpense,
            budgetLimit: budgetLimit,
            percentage: percentage,
          );
        }
      } catch (e) {
        // print('检查预算时出错: $e');
      }
    }
  }

  // 更新交易记录
  Future<void> updateTransaction(Transaction transaction) async {
    try {
      await _databaseService.updateTransaction(transaction);
      final index = _transactions.indexWhere((t) => t.id == transaction.id);
      if (index != -1) {
        _transactions[index] = transaction;
        _transactions.sort((a, b) => b.date.compareTo(a.date));
        await _convertTransactionsToBased();
        notifyListeners();
      }
    } catch (e) {
      debugPrint('更新交易记录时出错: $e');
      _hasError = true;
      notifyListeners();

      // 只在出错时同步到GitHub
      if (_dataSyncService != null) {
        try {
          final localData = {
            'transactions': _transactions.map((t) => t.toJson()).toList(),
            'lastSync': DateTime.now().toIso8601String(),
          };
          await _dataSyncService!.saveDataLocally(localData);
          await syncData(); // 同步到GitHub
        } catch (e) {
          debugPrint('自动同步失败: $e');
        }
      }
      rethrow;
    }
  }

  // 删除交易记录
  Future<void> deleteTransaction(String id) async {
    try {
      await _databaseService.deleteTransaction(id);
      _transactions.removeWhere((t) => t.id == id);
      await _convertTransactionsToBased();
      notifyListeners();
    } catch (e) {
      debugPrint('删除交易记录时出错: $e');
      _hasError = true;
      notifyListeners();

      // 只在出错时同步到GitHub
      if (_dataSyncService != null) {
        try {
          final localData = {
            'transactions': _transactions.map((t) => t.toJson()).toList(),
            'lastSync': DateTime.now().toIso8601String(),
          };
          await _dataSyncService!.saveDataLocally(localData);
          await syncData(); // 同步到GitHub
        } catch (e) {
          debugPrint('自动同步失败: $e');
        }
      }
      rethrow;
    }
  }

  // 按类别获取交易记录
  Future<void> loadTransactionsByCategory(Category category) async {
    _setLoading(true);

    try {
      _transactions =
          (await _databaseService.getTransactionsByCategory(
            category,
          )).cast<Transaction>();
      // 按日期排序（最新的在前）
      _transactions.sort((a, b) => b.date.compareTo(a.date));

      // 转换交易记录到基准货币
      await _convertTransactionsToBased();
    } catch (e) {
      // print('按类别加载交易记录时出错: $e');
    } finally {
      _setLoading(false);
    }
  }

  // 按日期范围获取交易记录
  Future<void> loadTransactionsByDateRange(
    DateTime startDate,
    DateTime endDate,
  ) async {
    _setLoading(true);

    try {
      _transactions =
          (await _databaseService.getTransactionsByDateRange(
            startDate,
            endDate,
          )).cast<Transaction>();
      // 按日期排序（最新的在前）
      _transactions.sort((a, b) => b.date.compareTo(a.date));

      // 转换交易记录到基准货币
      await _convertTransactionsToBased();
    } catch (e) {
      // print('按日期范围加载交易记录时出错: $e');
    } finally {
      _setLoading(false);
    }
  }

  // 从现有列表中按日期范围筛选交易记录 (同步)
  List<Transaction> getTransactionsInDateRange(
    DateTime startDate,
    DateTime endDate,
  ) {
    return _transactions
        .where(
          (t) =>
              !t.date.isBefore(startDate) &&
              !t.date.isAfter(endDate.add(const Duration(days: 1))),
        )
        .toList();
  }

  // 获取按类别分组的支出统计
  Map<Category, double> getExpenseStatsByCategory() {
    final Map<Category, double> stats = {};
    for (var transaction in expenseTransactions) {
      stats[transaction.category] =
          (stats[transaction.category] ?? 0) + transaction.amount;
    }
    return stats;
  }

  // 获取按类别分组的收入统计
  Map<Category, double> getIncomeStatsByCategory() {
    final Map<Category, double> stats = {};
    for (var transaction in incomeTransactions) {
      stats[transaction.category] =
          (stats[transaction.category] ?? 0) + transaction.amount;
    }
    return stats;
  }

  // 搜索交易记录
  Future<List<Transaction>> searchTransactions(String query) async {
    if (query.isEmpty) {
      return _convertedTransactions;
    }
    // Simple search in notes and category names for now
    final lowerCaseQuery = query.toLowerCase();
    return _convertedTransactions.where((t) {
      final noteMatch = t.note?.toLowerCase().contains(lowerCaseQuery) ?? false;
      final categoryMatch = t.category.name.toLowerCase().contains(
        lowerCaseQuery,
      );
      return noteMatch || categoryMatch;
    }).toList();
  }

  // 将所有交易记录转换为基准货币
  Future<void> _convertTransactionsToBased() async {
    final prefs = await SharedPreferences.getInstance();
    final baseCurrency = prefs.getString('currency') ?? 'CNY';

    final futures = _transactions.map((transaction) async {
      if (transaction.currency == baseCurrency) {
        return transaction;
      }
      final convertedAmount = await ExchangeRateService.convertAmount(
        transaction.amount,
        transaction.currency,
        baseCurrency,
      );
      return transaction.copyWith(
        amount: convertedAmount,
        currency: baseCurrency,
      );
    });

    _convertedTransactions = await Future.wait(futures);
    // Sort again, as conversion might affect order if dates are the same
    _convertedTransactions.sort((a, b) => b.date.compareTo(a.date));
  }

  // 刷新汇率并重新计算
  Future<void> refreshExchangeRates() async {
    if (_transactions.isNotEmpty) {
      _setLoading(true);
      try {
        // Re-converting will implicitly use cached or fetched rates
        await _convertTransactionsToBased();
      } catch (e) {
        // 刷新失败，保持当前状态
      } finally {
        _setLoading(false);
      }
    }
  }

  // 获取指定货币的总额（不转换）
  double getTotalIncomeByCurrency(String currency) {
    return _transactions
        .where(
          (t) => t.type == TransactionType.income && t.currency == currency,
        )
        .fold(0, (sum, t) => sum + t.amount);
  }

  double getTotalExpenseByCurrency(String currency) {
    return _transactions
        .where(
          (t) => t.type == TransactionType.expense && t.currency == currency,
        )
        .fold(0, (sum, t) => sum + t.amount);
  }

  // 获取所有使用的货币列表
  Set<String> getUsedCurrencies() {
    return _transactions.map((t) => t.currency).toSet();
  }

  // 批量插入交易记录（用于导入）
  Future<void> batchInsertTransactions(List<Transaction> transactions) async {
    for (final t in transactions) {
      await _databaseService.insertTransaction(t);
    }
    await loadTransactions();
  }

  // 删除所有数据
  Future<void> deleteAllData() async {
    _setLoading(true);
    try {
      final db = _databaseService;
      final allTransactions = await db.getTransactions();
      for (final t in allTransactions) {
        await db.deleteTransaction(t.id);
      }
      await loadTransactions();
    } catch (e) {
      // print('删除所有数据时出错: $e');
    } finally {
      _setLoading(false);
    }
  }

  // 安全地更新加载状态并通知监听器
  void _setLoading(bool loading) {
    Future.microtask(() {
      _isLoading = loading;
      notifyListeners();
    });
  }

  // 从GitHub下载数据
  Future<void> downloadFromGitHub() async {
    if (_isSyncing) return;

    try {
      _isSyncing = true;
      _hasError = false;
      notifyListeners();

      if (_dataSyncService == null) {
        throw Exception('数据同步服务未初始化，请重启应用');
      }

      // 从GitHub获取数据
      final data = await _dataSyncService!.fetchDataFromGitHub();

      // 验证数据格式
      if (data == null) {
        throw Exception('从GitHub获取的数据为空');
      }

      if (data['transactions'] == null) {
        throw Exception('下载的数据中缺少transactions字段');
      }

      if (data['transactions'] is! List) {
        throw Exception('下载的数据中transactions字段不是列表格式');
      }

      // 验证每个交易记录
      final List<dynamic> transactionsData =
          data['transactions'] as List<dynamic>;
      final List<Transaction> validTransactions = [];
      int invalidCount = 0;

      for (final transactionData in transactionsData) {
        try {
          // 验证必填字段
          if (transactionData['id'] == null ||
              transactionData['title'] == null ||
              transactionData['amount'] == null ||
              transactionData['date'] == null ||
              transactionData['type'] == null ||
              transactionData['category'] == null ||
              transactionData['currency'] == null) {
            debugPrint('交易记录缺少必填字段: $transactionData');
            invalidCount++;
            continue;
          }

          // 验证数值类型
          if (transactionData['amount'] is! num) {
            debugPrint('交易金额格式无效: ${transactionData['amount']}');
            invalidCount++;
            continue;
          }

          // 验证日期格式
          try {
            DateTime.parse(transactionData['date']);
          } catch (e) {
            debugPrint('交易日期格式无效: ${transactionData['date']}');
            invalidCount++;
            continue;
          }

          // 验证交易类型
          try {
            TransactionType.values.byName(transactionData['type']);
          } catch (e) {
            debugPrint('交易类型无效: ${transactionData['type']}');
            invalidCount++;
            continue;
          }

          // 验证分类
          try {
            Category.values.byName(transactionData['category']);
          } catch (e) {
            debugPrint('交易分类无效: ${transactionData['category']}');
            invalidCount++;
            continue;
          }

          // 创建交易记录
          final transaction = Transaction.fromJson(transactionData);
          validTransactions.add(transaction);
        } catch (e) {
          debugPrint('解析交易记录失败: $e');
          invalidCount++;
        }
      }

      if (validTransactions.isEmpty) {
        throw Exception('没有有效的交易记录可以导入');
      }

      // 清空现有数据
      await _databaseService.clearTransactions();

      // 批量插入有效交易记录
      await batchInsertTransactions(validTransactions);

      // 保存到本地缓存
      final localData = {
        'transactions': validTransactions.map((t) => t.toJson()).toList(),
        'lastSync': DateTime.now().toIso8601String(),
      };
      await _dataSyncService!.saveDataLocally(localData);

      _lastSyncTime = DateTime.now();
      _hasError = false;

      // 显示导入结果
      if (navigatorKey.currentContext != null) {
        ScaffoldMessenger.of(navigatorKey.currentContext!).showSnackBar(
          SnackBar(
            content: Text(
              '成功导入 ${validTransactions.length} 条记录${invalidCount > 0 ? '，跳过 $invalidCount 条无效记录' : ''}',
            ),
          ),
        );
      }
    } catch (e) {
      _hasError = true;
      debugPrint('从GitHub下载数据失败: $e');
      rethrow;
    } finally {
      _isSyncing = false;
      notifyListeners();
    }
  }
}
